package com.myframe.www.net;

import android.app.Application;
import android.text.TextUtils;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.myframe.www.model.local.UserCenter;
import com.myframe.www.net.gson.GsonConverterFactory;
import com.yong.android.framework.utils.log.SLog;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import retrofit2.Retrofit;


/**
 * Description:
 * Created by Andy Hong on 10/19/2017.
 */

public class HttpHandler {
    private static Retrofit retrofit;

    public static void initialize(Application application) {
        OkHttpClient okHttpClient = new OkHttpClient
                .Builder()
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .addInterceptor(new AuthorizationInterceptor())
                .addInterceptor(new RequestInfoInterceptor())
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(HttpURL.URL_BASE)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }

    public static <T> T create(Class<T> service) {
        return retrofit.create(service);
    }


    private static class RequestInfoInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("method:").append(request.method()).append("\n");
            stringBuilder.append("URL:").append(request.url().toString()).append("\n");
            stringBuilder.append("header:").append(request.headers().toString()).append("\n");

            RequestBody body = request.body();
            if (body instanceof MultipartBody) {
                stringBuilder.append(getMultipartBodyInfo((MultipartBody) body));
            } else if (body instanceof FormBody) {
                 stringBuilder.append(getFormBodyInfo((FormBody) body));
            }
            SLog.d(stringBuilder.toString());
            return chain.proceed(request);
        }

        private static String getMultipartBodyInfo(MultipartBody multipartBody) {
            List<MultipartBody.Part> parts = multipartBody.parts();
            if (parts.size() != 0) {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append("MultipartBodyInfo: \n");
                for (int i = 0; i < parts.size(); i++) {
                    MultipartBody.Part part = parts.get(i);
                    stringBuilder.append("part: \n");
                    stringBuilder.append("part: ").append(part.headers().toString()).append("\n");
                    String length;
                    try {
                        length = String.valueOf(part.body().contentLength());
                    } catch (IOException e) {
                        length = "can't get the content length";
                    }
                    stringBuilder.append("mediaType: ").append(part.body().contentType())
                            .append("length: ").append(length);

                }
                return stringBuilder.toString();
            } else {
                return "no multipart body info";
            }

        }

        private static String getFormBodyInfo(FormBody formBody) {
            int size = formBody.size();
            if (size != 0) {
                StringBuilder stringBuilder = new StringBuilder("FormBodyInfo: \n");
                for (int index = 0; index < size; index++) {
                    stringBuilder.append("name: ").append(formBody.name(index))
                            .append(" value: ").append(formBody.value(index)).append("\n");
                }
                return stringBuilder.toString();
            } else {
                return "no form body info";
            }

        }
    }

    private static class AuthorizationInterceptor implements Interceptor {
        private AuthorizationV2 auth;

        public AuthorizationInterceptor() {
            auth = new AuthorizationV2();
        }

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            String authHeader = request.header(ServerField.HEADER_AUTH);

            if (!TextUtils.isEmpty(authHeader)) {
                if (authHeader.equals("Y")) {

                    String newAuthHeader = auth.createAuthorization(UserCenter.getLoginBean(), request.url().toString(), request.method());
                    return chain.proceed(request.newBuilder()
                            .header(ServerField.HEADER_AUTH, newAuthHeader)
                            .build());
                }
            }
            return chain.proceed(request);
        }


    }

}
